#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define MAX_BUFFER_SIZE 10240
#define PACKET_HEADER_SIZE 12
#define MAGIC_NUMBER 0xABCD

// 数据包头结构
typedef struct {
    unsigned short magic;      // 魔术字，用于识别数据包
    unsigned int dataLength;   // JSON数据长度
    unsigned char dataType;    // 数据类型
    unsigned char flags;       // 标志位
    unsigned short reserved;   // 保留字段
} PacketHeader;

// 数据类型枚举
enum DataType {
    DATA_TYPE_SILICON_WAFER = 1,  // 硅片数据
    DATA_TYPE_PRODUCTION = 2,     // 生产数据
    DATA_TYPE_HEARTBEAT = 3,      // 心跳包
    DATA_TYPE_ACK = 4,            // 确认包
    DATA_TYPE_ERROR = 5           // 错误包
};

// 特殊字符，用于解决粘包问题
#define START_DELIMITER 0x01  // 开始分隔符
#define END_DELIMITER 0x02    // 结束分隔符

// 错误码枚举
enum ErrorCode {
    ERROR_SUCCESS = 0,
    ERROR_INVALID_PACKET = 1,
    ERROR_JSON_PARSE = 2,
    ERROR_SOCKET = 3,
    ERROR_TIMEOUT = 4,
    ERROR_UNKNOWN = 99
};

// 初始化数据包头部
void initPacketHeader(PacketHeader *header, unsigned int dataLength, unsigned char dataType) {
    header->magic = MAGIC_NUMBER;
    header->dataLength = dataLength;
    header->dataType = dataType;
    header->flags = 0;
    header->reserved = 0;
}

// 验证数据包头部
int validatePacketHeader(PacketHeader *header) {
    if (header->magic != MAGIC_NUMBER) {
        return 0;  // 无效的魔术字
    }
    if (header->dataLength > MAX_BUFFER_SIZE) {
        return 0;  // 数据长度超过限制
    }
    return 1;
}

// 发送数据包
int sendPacket(int sockfd, unsigned char dataType, const char *jsonData) {
    int jsonLen = strlen(jsonData);
    int packetLen = PACKET_HEADER_SIZE + jsonLen + 2;  // 头部 + JSON数据 + 分隔符
    char *buffer = (char *)malloc(packetLen);
    if (!buffer) {
        return -1;
    }

    // 构建数据包
    buffer[0] = START_DELIMITER;
    
    PacketHeader *header = (PacketHeader *)(buffer + 1);
    initPacketHeader(header, jsonLen, dataType);
    
    memcpy(buffer + 1 + PACKET_HEADER_SIZE, jsonData, jsonLen);
    buffer[1 + PACKET_HEADER_SIZE + jsonLen] = END_DELIMITER;

    // 发送数据包
    int bytesSent = send(sockfd, buffer, packetLen, 0);
    free(buffer);
    
    return bytesSent;
}

// 接收数据包
int recvPacket(int sockfd, char *jsonBuffer, unsigned int bufferSize, unsigned char *dataType) {
    char recvBuffer[MAX_BUFFER_SIZE * 2];
    int pos = 0;
    int state = 0;  // 0: 寻找开始分隔符, 1: 读取头部, 2: 读取JSON数据
    PacketHeader header;
    int jsonLen = 0;

    while (1) {
        int bytesRead = recv(sockfd, recvBuffer + pos, sizeof(recvBuffer) - pos - 1, 0);
        if (bytesRead <= 0) {
            return -1;
        }
        pos += bytesRead;
        recvBuffer[pos] = '\0';

        int i = 0;
        while (i < pos) {
            if (state == 0) {
                // 寻找开始分隔符
                if (recvBuffer[i] == START_DELIMITER) {
                    state = 1;
                    i++;
                } else {
                    i++;
                }
            } else if (state == 1) {
                // 读取头部
                if (pos - i >= PACKET_HEADER_SIZE) {
                    memcpy(&header, recvBuffer + i, PACKET_HEADER_SIZE);
                    if (!validatePacketHeader(&header)) {
                        state = 0;  // 无效头部，重新寻找开始分隔符
                        i += PACKET_HEADER_SIZE;
                    } else {
                        jsonLen = header.dataLength;
                        *dataType = header.dataType;
                        state = 2;
                        i += PACKET_HEADER_SIZE;
                    }
                } else {
                    break;  // 头部不完整，继续接收
                }
            } else if (state == 2) {
                // 读取JSON数据和结束分隔符
                if (pos - i >= jsonLen + 1) {
                    if (recvBuffer[i + jsonLen] == END_DELIMITER) {
                        // 找到完整的数据包
                        if (jsonLen < bufferSize) {
                            memcpy(jsonBuffer, recvBuffer + i, jsonLen);
                            jsonBuffer[jsonLen] = '\0';
                            
                            // 移动剩余数据到缓冲区开头
                            memmove(recvBuffer, recvBuffer + i + jsonLen + 1, pos - (i + jsonLen + 1));
                            pos = pos - (i + jsonLen + 1);
                            
                            return jsonLen;
                        } else {
                            // JSON数据超过缓冲区大小
                            state = 0;
                            i += jsonLen + 1;
                        }
                    } else {
                        // 没有找到结束分隔符，重新寻找开始分隔符
                        state = 0;
                        i++;
                    }
                } else {
                    break;  // JSON数据不完整，继续接收
                }
            }
        }

        // 移动剩余数据到缓冲区开头
        memmove(recvBuffer, recvBuffer + i, pos - i);
        pos = pos - i;
    }
}

// 创建TCP服务器
int createTCPServer(int port, int backlog) {
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket creation failed");
        return -1;
    }

    // 设置套接字选项
    int opt = 1;
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) {
        perror("setsockopt failed");
        close(sockfd);
        return -1;
    }

    struct sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(port);

    if (bind(sockfd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("bind failed");
        close(sockfd);
        return -1;
    }

    if (listen(sockfd, backlog) < 0) {
        perror("listen failed");
        close(sockfd);
        return -1;
    }

    return sockfd;
}

// 连接TCP服务器
int connectTCPServer(const char *ipAddress, int port) {
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket creation failed");
        return -1;
    }

    struct sockaddr_in serv_addr;
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(port);

    if (inet_pton(AF_INET, ipAddress, &serv_addr.sin_addr) <= 0) {
        perror("invalid address");
        close(sockfd);
        return -1;
    }

    if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        perror("connection failed");
        close(sockfd);
        return -1;
    }

    return sockfd;
}

// 打印错误信息
void printError(const char *message, int errorCode) {
    fprintf(stderr, "Error: %s (Code: %d)\n", message, errorCode);
}